//
//  DBHelper+Reader.m
//  KidReading
//
//  Created by Telen on 16/4/10.
//  Copyright © 2016年 刘赞黄Telen. All rights reserved.
//

#import "DBHelper+Reader.h"
#import "ConstDefine.h"

@implementation TABLE_BOOK_Base
@end
@implementation TABLE_BOOKS
+ (NSString*)tableName{return @"book";}
+ (NSString *)primaryKey{return @"primary key(bookId)";};
- (NSString *)byPrimaryKey{return [NSString stringWithFormat:@" bookId=%ld ",(long)_bookId];}

- (NSDictionary *)listInfo {
    NSMutableDictionary *listInfo = [NSMutableDictionary dictionary];
    if (_parts) {
        NSData* data = [_parts dataUsingEncoding:NSUTF8StringEncoding];
        NSArray* arr = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        if (arr && arr.count > 0) {
            id item = arr[0];
            if ([item isKindOfClass:[NSDictionary class]]) {
                [listInfo setValue:[self partsArr] forKey:TBKey_Parts];
            }
        }
    }
    if (_beforeParts) {
        NSData* data = [_beforeParts dataUsingEncoding:NSUTF8StringEncoding];
        NSArray* arr = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        if (arr && arr.count > 0) {
            id item = arr[0];
            if ([item isKindOfClass:[NSDictionary class]]) {
                [listInfo setValue:[self beforePartsArr] forKey:TBKey_BeforeParts];
            }
        }
    }
    if (_afterParts) {
        NSData* data = [_afterParts dataUsingEncoding:NSUTF8StringEncoding];
        NSArray* arr = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        if (arr && arr.count > 0) {
            id item = arr[0];
            if ([item isKindOfClass:[NSDictionary class]]) {
                [listInfo setValue:[self afterPartArr] forKey:TBKey_AfterParts];
            }
        }
    }
    return listInfo;
}

- (NSArray *)partsArr
{
    if (_parts) {
        NSData* data = [_parts dataUsingEncoding:NSUTF8StringEncoding];
        NSArray* arr = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        NSMutableArray *urlArr = [NSMutableArray array];
        if (arr && arr.count > 0) {
            id item = arr[0];
            if ([item isKindOfClass:[NSDictionary class]]) {
                for (NSDictionary *dict in arr) {
                    NSMutableDictionary *mdict = [NSMutableDictionary dictionaryWithDictionary:dict];
                    [mdict setValue:TBKey_Parts forKey:TBKey_SortMark];
                    [urlArr addObject:mdict];
                }
            }else {
                return arr;
            }
            return urlArr;
        }
    }
    return @[];
}

- (NSArray *)beforePartsArr {
    if (_beforeParts) {
        NSData* data = [_beforeParts dataUsingEncoding:NSUTF8StringEncoding];
        NSArray* arr = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        NSMutableArray *urlArr = [NSMutableArray array];
        if (arr && arr.count > 0) {
            id item = arr[0];
            if ([item isKindOfClass:[NSDictionary class]]) {
                for (NSDictionary *dict in arr) {
                    NSMutableDictionary *mdict = [NSMutableDictionary dictionaryWithDictionary:dict];
                    [mdict setValue:TBKey_BeforeParts forKey:TBKey_SortMark];
                    [urlArr addObject:mdict];
                }
            }else {
                return arr;
            }
            return urlArr;
        }
    }
    return @[];
}

- (NSArray *)afterPartArr {
    if (_afterParts) {
        NSData* data = [_afterParts dataUsingEncoding:NSUTF8StringEncoding];
        NSArray* arr = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        NSMutableArray *urlArr = [NSMutableArray array];
        if (arr && arr.count > 0) {
            id item = arr[0];
            if ([item isKindOfClass:[NSDictionary class]]) {
                for (NSDictionary *dict in arr) {
                    NSMutableDictionary *mdict = [NSMutableDictionary dictionaryWithDictionary:dict];
                    [mdict setValue:TBKey_AfterParts forKey:TBKey_SortMark];
                    [urlArr addObject:mdict];
                }
            }else {
                return arr;
            }
            return urlArr;
        }
    }
    return @[];
}

@end

@implementation TABLE_SUPPORT_FILE
+ (NSString*)tableName{return @"support_file";}
+ (NSString *)primaryKey{return @"primary key(sfKey)";};
- (NSString *)byPrimaryKey{return [NSString stringWithFormat:@" sfKey='%@'",_sfKey];}
@end

@implementation TABLE_TIMESTAMP_LAST
+ (NSString*)tableName{return @"timestamp_last";}
+ (NSString *)primaryKey{return @"primary key(name)";};
- (NSString *)byPrimaryKey{return [NSString stringWithFormat:@" name=%@",_name];}
@end
@implementation TABLE_TIMESTAMP
+ (NSString*)tableName{return @"timestamp";}
+ (NSString *)primaryKey{return @"primary key(userId)";};
- (NSString *)byPrimaryKey{return [NSString stringWithFormat:@" userId=%ld",(long)_userId];}
@end

@implementation TABLE_NOTICE
+ (NSString*)tableName{return @"notice";}
+ (NSString *)primaryKey{return @"primary key(noticeId)";};
- (NSString *)byPrimaryKey{return [NSString stringWithFormat:@" noticeId=%ld",(long)_noticeId];}
@end

@implementation TABLE_QUIZ
+ (NSString*)tableName{return @"quiz";}
+ (NSString *)primaryKey{return @"primary key(bookId)";};
- (NSString *)byPrimaryKey{return [NSString stringWithFormat:@" bookId=%ld",(long)_bookId];}
@end

@implementation TABLE_TALK_LIST
+ (NSString *)tableName{return @"talk_list";}
+ (NSString *)primaryKey{return @"primary key(talkId)";}
- (NSString *)byPrimaryKey{return [NSString stringWithFormat:@" talkId=%ld",(long)_talkId];}
@end

@implementation TABLE_TALK_VEDIO_LIST
+ (NSString *)tableName{return @"talk_video_list";}
+ (NSString *)primaryKey{return @"primary key(videoId)";}
- (NSString *)byPrimaryKey{return [NSString stringWithFormat:@" videoId=%ld",(long)_videoId];}
@end

@implementation TABLE_READING_COUNT
+ (NSString*)tableName{return @"readingCount";}
+ (NSString *)primaryKey{return @"primary key(bookId)";};
- (NSString *)byPrimaryKey{return [NSString stringWithFormat:@" bookId=%ld",(long)_bookId];}
@end

#pragma mark
@implementation DBHelper (Reader)
ASSOCIATED(dbQue, setDbQue, JRFMDatabaseQueue*, OBJC_ASSOCIATION_RETAIN_NONATOMIC)
ASSOCIATED(tb_lastTime, setTb_lastTime, TABLE_TIMESTAMP_LAST*, OBJC_ASSOCIATION_RETAIN_NONATOMIC)
ASSOCIATED_BOOL(isLimitedTimeForNet, setIsLimitedTimeForNet)
ASSOCIATED_BOOL(isSpotlightClear, setIsSpotlightClear);

+ (void)load{
    [self swizzleSelector:@selector(init) withSelector:@selector(init_Reader)];
}

- (void)tb_lastTime_init:(JRFMDatabase*)db
{
    if (self.tb_lastTime == nil) {
        NSString* name = @"lasttime";
        NSArray *list = [self getList_fromTableClass:NSStringFromClass([TABLE_TIMESTAMP_LAST class]) where:[NSString stringWithFormat:@" where name='%@'",name] db:db];
        self.tb_lastTime= [list firstObject];
    }
}

- (void)update_VersionForMasterDB:(JRFMDatabase*)db
{
    long ver = [JRFMDatabase JRFMDB_getVersionFromDB:db];
    if (ver <= 4) {
        [JRFMDatabase JRFMDB_setDB:db version:4];//Version 3.1开发使用
    }
}

- (instancetype)init_Reader
{
    self = [self init_Reader];
    if (self) {
        BOOL debugDB = YES;
#if __KeyForDB_ON_
        debugDB = NO;
#endif
        NSString* path = [self getDBPath:__DBFileName debugPath:__DBFileName_debug dbKey:__KeyForDB_ dbebug:debugDB];
        if([self dbFile_initForDBPath:path]){
            if (![DataProcessing iOS9_low]) {
                //Spotlight 系统搜索，清空图书缓存
                [[CSSearchableIndex defaultSearchableIndex] deleteSearchableItemsWithDomainIdentifiers:@[@"books.wawayaya.com"] completionHandler:nil];
                self.isSpotlightClear = YES;
            }
        }
        self.dbQue = [JRFMDatabaseQueue databaseQueueWithPath:path];
        [self.dbQue inDatabase:^(JRFMDatabase *db) {
#if __KeyForDB_ON_
            if (![db setKey:__KeyForDB_]) {
                NSLog(@"setkey failed");
            };
#endif
            [db executeUpdate:[TABLE_BOOKS createTable]];
            [db executeUpdate:[TABLE_SUPPORT_FILE createTable]];
            [db executeUpdate:[TABLE_TIMESTAMP createTable]];
            [db executeUpdate:[TABLE_NOTICE createTable]];
            [db executeUpdate:[TABLE_QUIZ createTable]];
            //
            [db executeUpdate:[TABLE_TALK_LIST createTable]];
            [db executeUpdate:[TABLE_TALK_VEDIO_LIST createTable]];
            [db executeUpdate:[TABLE_READING_COUNT createTable]];
            //
            [db executeUpdate:[TABLE_TIMESTAMP_LAST createTable]];
            //
            //
            [self update_VersionForMasterDB:db];
            [self tb_lastTime_init:db];
            //
        }];
    }
    return self;
}

#pragma mark- Select
- (void)readerDB_getList:(void(^)(NSArray* list))retlist fromTableClass:(NSString *)tableClassName where:(NSString *)sql
{
    [self readerDB_getDictList:^(NSArray *list) {
        [DataProcessing do_Async_quick:^{
            NSMutableArray* marr = [NSMutableArray new];
            [list enumerateObjectsUsingBlock:^(NSDictionary*  _Nonnull dict, NSUInteger idx, BOOL * _Nonnull stop) {
                id obj = [NSClassFromString(tableClassName) JRMJ_objectWithKeyValues:dict];
                if ([obj isKindOfClass:[TABLE_base class]]) {
                    NSDictionary* replaceKeys = [[obj class] replacedKeyFromPropertyName];
                    for (NSString* key in replaceKeys) {
                        id value = dict[key];
                        if (value && [obj hasProperty:key]) {
                            [obj setValue:value forKey:key];
                        }
                    }
                }
                if (obj) {
                    [marr addObject:obj];
                }
            }];
            [DataProcessing do_Main_quick:^{
                retlist(marr);
            }];
        }];
    } fromTableClass:tableClassName where:sql];
}

- (void)readerDB_getDictList:(void(^)(NSArray* list))retlist fromTableClass:(NSString *)tableClassName where:(NSString *)sql
{
    [DataProcessing do_Async_quick:^{
        [self.dbQue inTransaction:^(JRFMDatabase *db, BOOL *rollback) {
            NSArray * arr = [self getDictList_fromTableClass:tableClassName where:sql db:db];
            [DataProcessing do_Main_quick:^{
                retlist(arr);
            }];
        }];
    }];
}

#pragma mark- Update
- (void)readerDB_updateListToTableClass:(NSString *)tableClassName dictArr:(NSArray*)dictList complete:(void (^)(void))comp
{
    [DataProcessing do_Async_quick:^{
        [self.dbQue inTransaction:^(JRFMDatabase *db, BOOL *rollback) {
            [self updateListToTableClass:tableClassName dictArr:dictList db:db];
            if (comp) {
                [DataProcessing do_Main_quick:^{
                    comp();
                }];
            }
        }];
    }];
}

#pragma mark- Delete
- (void)readerDB_deletListToTableClass:(NSString *)tableClassName dictArr:(NSArray*)dictList complete:(void (^)(void))comp
{
    [DataProcessing do_Async_quick:^{
        [self.dbQue inTransaction:^(JRFMDatabase *db, BOOL *rollback) {
            [self deletListToTableClass:tableClassName dictArr:dictList db:db];
            if (comp) {
                [DataProcessing do_Main_quick:^{
                    comp();
                }];
            }
        }];
    }];
}

#pragma mark- Delete_TableBase
- (void)readerDB_deletListToTableClass:(NSString *)tableClassName tbArr:(NSArray*)dictList complete:(void (^)(void))comp
{
    [DataProcessing do_Async_quick:^{
        [self.dbQue inTransaction:^(JRFMDatabase *db, BOOL *rollback) {
            [self deletListToTableClass:tableClassName tbArr:dictList db:db];
            if (comp) {
                [DataProcessing do_Main_quick:^{
                    comp();
                }];
            }
        }];
    }];
}


#pragma mark-
#pragma mark- sql
- (void)readerDB_inQueue_executeUpdate:(NSString*)str complete:(void (^)(void))comp
{
    [DataProcessing do_Async_quick:^{
        [self.dbQue inTransaction:^(JRFMDatabase *db, BOOL *rollback) {
            [db executeUpdate:str];
            if (comp) {
                [DataProcessing do_Main_quick:^{
                    comp();
                }];
            }
            
        }];
    }];
}

#pragma mark-
- (void)readerDB:(void (^)(JRFMDatabase *))dbDo
{
    [DataProcessing do_Async_quick:^{
        [self.dbQue inTransaction:^(JRFMDatabase *db, BOOL *rollback) {
            if(dbDo)dbDo(db);
        }];
    }];
}

#pragma mark-
- (void)readerDB_countForTableName:(NSString *)tableClassName where:(NSString*)where complete:(void(^)(NSInteger))comp
{
    [DataProcessing do_Async_quick:^{
        [self.dbQue inTransaction:^(JRFMDatabase *db, BOOL *rollback) {
            NSInteger count = [db intForQuery:[NSString stringWithFormat:@"select count(*) from %@ %@ ",tableClassName,where]];
            [DataProcessing do_Main_quick:^{
                if(comp)comp(count);
            }];
        }];
    }];
}

- (void)readerDB_maxForTableName:(NSString *)tableClassName key:(NSString*)key where:(NSString*)where complete:(void(^)(LongLong))comp
{
    [DataProcessing do_Async_quick:^{
        [self.dbQue inTransaction:^(JRFMDatabase *db, BOOL *rollback) {
            LongLong num = [db doubleForQuery:[NSString stringWithFormat:@"select max(%@) from %@ %@ ",key,tableClassName,where]];
            [DataProcessing do_Main_quick:^{
                if(comp)comp(num);
            }];
        }];
    }];
}

- (void)readerDB_minForTableName:(NSString *)tableClassName key:(NSString*)key where:(NSString*)where complete:(void(^)(LongLong))comp
{
    [DataProcessing do_Async_quick:^{
        [self.dbQue inTransaction:^(JRFMDatabase *db, BOOL *rollback) {
            LongLong num = [db doubleForQuery:[NSString stringWithFormat:@"select min(%@) from %@ %@ ",key,tableClassName,where]];
            [DataProcessing do_Main_quick:^{
                if(comp)comp(num);
            }];
        }];
    }];
}


@end
